//
//  HUD.swift
//  
//
//  Created by bo wang on 2021/1/6.
//  Copyright © 2021 wangbo. All rights reserved.
//

import UIKit
import MBProgressHUD

class HUD: MBProgressHUD {
    
    private static weak var _defaultWindow: UIWindow?
    
    /// 可以为HUD指定一个默认显示的 window，当 inView 参数为 nil 时，HUD将显示在此 window 上。
    /// 没有设置或者设置值为nil或者设置的window被释放时，返回当前 keyWindow
    static weak var defaultWindow: UIWindow? {
        get {
            return _defaultWindow ?? UIApplication.shared.keyWindow
        }
        set {
            _defaultWindow = newValue
        }
    }
    
    /// 显示时长
    static var duration: TimeInterval = 1.5
    /// 限制行数
    static var linesLimit: Int = 8
    /// 成功图片
    static var sucImage: UIImage? // = R.image.main_img_hud_success()
    /// 失败图片
    static var failImage: UIImage? // = R.image.main_img_hud_failure()
    
    /// 展示一个简单的Loading样式HUD，需要外部主动隐藏
    /// - Returns: HUD实例
    @discardableResult @objc
    static func show() -> HUD {
        return showLoading()
    }
    
    /// 显示一个Loading样式的HUD，包含简单文本内容，需要外部主动隐藏
    /// - Parameters:
    ///   - msg: 文本内容，为nil时不显示文本
    ///   - delay: 延迟时长，默认为0，直接显示
    ///   - view: 指定容器View，默认为nil
    /// - Returns: HUD实例
    @discardableResult @objc
    static func showLoading(msg: String? = nil,
                            delay: TimeInterval = 0,
                            in view: UIView? = nil)
    -> HUD {
        return showLoadingHUD(plain: msg, delay: delay, in: view)
    }
    
    /// 展示简单的文本HUD
    /// - Parameter msg: 文本内容，为nil时什么都不显示
    /// - Parameter delay: 延迟时长，默认为0，直接显示
    /// - Parameter view: 指定容器View，默认为nil
    /// - Returns: HUD实例
    @discardableResult @objc
    static func show(msg: String?,
                     delay: TimeInterval = 0,
                     in view: UIView? = nil)
    -> HUD {
        return showAutoHideHUD(plain: msg, delay: delay, in: view)
    }
    
    /// 展示一个自动隐藏的HUD，包含图片和文本
    /// - Parameters:
    ///   - plain: 文本内容
    ///   - attributedString: 富文本内容
    ///   - image: 图片内容
    ///   - inView: 指定容器View，默认为nil
    ///   - delay: 延迟时长，默认为0，直接显示
    /// - Returns: HUD
    @discardableResult
    private static func showAutoHideHUD(plain: String? = nil,
                                        attributedString: NSAttributedString? = nil,
                                        image: UIImage? = nil,
                                        delay: TimeInterval = 0,
                                        in inView: UIView? = nil)
    -> HUD {
        let view = inView ?? Self.defaultWindow
        let hud = HUD()
        hud.removeFromSuperViewOnHide = true
        hud.minShowTime = Self.duration
        hud.areDefaultMotionEffectsEnabled = true
        if #available(iOS 13, *) {
            hud.bezelView.blurEffectStyle = .systemThinMaterialDark
        } else {
            hud.bezelView.blurEffectStyle = .dark
        }
        hud.contentColor = .white
        
        if let img = image {
            hud.mode = .customView
            hud.customView = UIImageView(image: img)
        } else {
            hud.mode = .text
        }
        
        hud.label.numberOfLines = linesLimit
        if let text = plain {
            hud.label.text = text
        } else if let text = attributedString {
            hud.label.attributedText = text
        } else {
            hud.label.text = ""
        }
        
        DispatchQueue.main.asyncAfter(deadline: .now() + max(0, delay)) {
            view?.addSubview(hud)
            hud.show(animated: true)
            hud.hide(animated: true, afterDelay: Self.duration)
        }
        return hud
    }
    
    /// 显示一个Loading的HUD，可包含文本/富文本内容，需要外部手动隐藏。
    /// - Parameters:
    ///   - plain: 文本内容
    ///   - attributedString: 富文本内容
    ///   - delay: 延迟显示时间，默认为0
    ///   - inView: 指定容器View，默认为nil
    /// - Returns: HUD实例
    @discardableResult
    private static func showLoadingHUD(plain: String? = nil,
                                       attributedString: NSAttributedString? = nil,
                                       delay: TimeInterval = 0,
                                       in inView: UIView? = nil)
    -> HUD {
        let view = inView ?? Self.defaultWindow
        let hud = HUD()
        hud.removeFromSuperViewOnHide = true
        hud.minShowTime = Self.duration
        hud.areDefaultMotionEffectsEnabled = true
        hud.mode = .indeterminate
        hud.bezelView.blurEffectStyle = .dark
        hud.contentColor = .white

        hud.label.numberOfLines = linesLimit
        if let text = plain {
            hud.label.text = text
        } else if let text = attributedString {
            hud.label.attributedText = text
        } else {
            hud.label.text = nil
        }
        
        DispatchQueue.main.asyncAfter(deadline: .now() + max(0, delay)) {
            view?.addSubview(hud)
            hud.show(animated: true)
        }
        return hud
    }
    
    func hideForced() {
        minShowTime = 0
        hide(animated: false)
    }
}

// MARK: Suc/Fail
extension HUD {
    /// 展示成功状态的文本HUD，成功图标为 HUD.sucImage
    /// - Parameter msg: 文本内容，为nil时只显示icon
    /// - Parameter delay: 延迟时长，默认为0，直接显示
    /// - Parameter view: 指定容器View，默认为nil
    /// - Returns: HUD实例
    @discardableResult @objc
    static func showSuc(msg: String? = nil,
                        delay: TimeInterval = 0,
                        in view: UIView? = nil)
    -> HUD {
        return showAutoHideHUD(plain: msg, image: sucImage, delay: delay, in: view)
    }
    
    /// 展示失败状态的文本HUD，失败图标为 HUD.failImage
    /// - Parameter msg: 文本内容，为nil时只显示icon
    /// - Parameter delay: 延迟时长，默认为0，直接显示
    /// - Parameter view: 指定容器View，默认为nil
    /// - Returns: HUD实例
    @discardableResult @objc
    static func showFail(msg: String? = nil,
                         delay: TimeInterval = 0,
                         in view: UIView? = nil)
    -> HUD {
        return showAutoHideHUD(plain: msg, image: failImage, delay: delay, in: view)
    }
}

//// MARK: HTML
//extension HUD {
//    /// 展示一个自动隐藏的HUD，包含图片和html富文本内容
//    /// - Parameters:
//    ///   - html: HTML字符串
//    ///   - image: 图片内容
//    ///   - delay: 延迟时长，默认为0，直接显示
//    ///   - view: 指定容器View，默认为nil
//    /// - Returns: HUD
//    @discardableResult @objc
//    static func show(html: String,
//                     image: UIImage? = nil,
//                     delay: TimeInterval = 0,
//                     in view: UIView? = nil)
//    -> HUD {
//        return showAutoHideHUD(attributedString: html.attributedHTMLRichText(), image: image, delay: delay, in: view)
//    }
//
//    /// 显示一个Loading样式的HUD，包含富文本内容，需要外部手动隐藏
//    /// - Parameters:
//    ///   - html: HTML字符串
//    ///   - delay: 延迟时长，默认为0，直接显示
//    ///   - view: 指定容器View，默认为nil
//    /// - Returns: HUD实例
//    @discardableResult @objc
//    static func showLoading(html: String,
//                            delay: TimeInterval = 0,
//                            in view: UIView? = nil)
//    -> HUD {
//        return showLoadingHUD(attributedString: html.attributedHTMLRichText(), delay: delay, in: view)
//    }
//}
